package com.ynet.middleground.riskmanage.utils;

import org.apache.log4j.Logger;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

/**
 * 航信用的加密工具
 */
public class TripleDESUtil {

    private static final String Algorithm = "DESede"; // 定义 加密算法,可用 DES,DESede,Blowfish
    private final static Logger log = Logger.getLogger(TripleDESUtil.class);

    /**
     * 加密算法 password为加密密钥，长度为24字节 src为被加密的数据缓冲区（源）
     *
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    public static byte[] encryptMode(String password, byte[] src) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        // 生成密钥
        SecretKey deskey = new SecretKeySpec(password.getBytes(), Algorithm);
        // 加密
        Cipher c1 = Cipher.getInstance(Algorithm);
        c1.init(Cipher.ENCRYPT_MODE, deskey);
        return c1.doFinal(src);
    }

    /**
     * 解密算法 keybyte为加密密钥，长度为24字节 src为被加密的数据缓冲区（源）
     *
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    public static byte[] decryptMode(String password, byte[] src) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        // 生成密钥
        SecretKey deskey = new SecretKeySpec(password.getBytes(), Algorithm);
        // 解密
        Cipher c1 = Cipher.getInstance(Algorithm + "/ECB/NoPadding");
        c1.init(Cipher.DECRYPT_MODE, deskey);
        System.out.println("待解密内容长度" + src.length);
        return c1.doFinal(src);
    }

    // 转换成十六进制字符串
    private static String byte2hex(byte[] b) {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (int n = 0; b != null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1)
                hs.append('0');
            hs.append(stmp);
        }
        return hs.toString().toUpperCase();
    }

    public static String bytes2HexString(byte[] b) {
        String r = "";

        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            r += hex.toUpperCase();
        }

        return r;
    }

    /*
     * 字符转换为字节
     */
    private static byte charToByte(char c) {
        return (byte)"0123456789ABCDEF".indexOf(c);
    }

    /*
     * 16进制字符串转字节数组
     */
    public static byte[] hexString2Bytes(String hex) {

        if ((hex == null) || (hex.equals(""))) {
            return null;
        } else if (hex.length() % 2 != 0) {
            return null;
        } else {
            hex = hex.toUpperCase();
            int len = hex.length() / 2;
            byte[] b = new byte[len];
            char[] hc = hex.toCharArray();
            for (int i = 0; i < len; i++) {
                int p = 2 * i;
                b[i] = (byte)(charToByte(hc[p]) << 4 | charToByte(hc[p + 1]));
            }
            return b;
        }

    }

    /**
     * BASE64加密
     */
    public static byte[] encode(byte[] res) {
        try {
            return org.apache.commons.codec.binary.Base64.encodeBase64(res);
        } catch (Exception e) {
            log.error("base64解码失败", e);
            return null;
        }
    }

    public static byte[] decode(byte[] data) {
        return org.apache.commons.codec.binary.Base64.decodeBase64(data);
    }

    public static String getRandomNum() {
        int a[] = new int[10];
        String result = "";
        for (int i = 0; i < a.length; i++) {
            a[i] = (int)(10 * (Math.random()));
            result = result + a[i] + "";
        }
        return result;
    }

    public static int getRangeRandom(int max, int min) {
        Random random = new Random();
        // System.out.print(s);
        return random.nextInt(max - min + 1) + min;
    }

    public static String getRandomNum(int Num) {
        int a[] = new int[Num];
        String result = "";
        for (int i = 0; i < a.length; i++) {
            a[i] = (int)(10 * (Math.random()));
            result = result + a[i] + "";
        }
        return result;
    }

    public static byte[] MD5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest mdTemp = MessageDigest.getInstance("MD5");
        mdTemp.update(str.getBytes("UTF-8"));
        byte[] digest = mdTemp.digest();
        return digest;
    }

    public static String HMACSHA256(byte[] data, byte[] key) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA256");
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(signingKey);
            return byte2hex(mac.doFinal(data));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String xml = "<?xml version=\"1.0\" encoding=\"GBK\"?>\n" + "<FPKJINPUT> \n" + "  <INPUT> \n"
            + "    <QYSH>500102202508227030</QYSH>\n" + "    <KPZDH>34</KPZDH>  \n" + "    <ZFJH>34</ZFJH>  \n"
            + "    <FPLSH>zmy20210823001</FPLSH>  \n" + "    <FPTQM>00</FPTQM>  \n" + "    <FPZL>51</FPZL>  \n"
            + "    <KPLX>1</KPLX>  \n" + "    <KPMS>1</KPMS>  \n" + "    <KPLY>1</KPLY>  \n"
            + "    <XFSH>500102202508227030</XFSH>  \n" + "    <XFMC>宁国市詹瞻澹再生</XFMC>  \n"
            + "    <XFDZDH>www.saik</XFDZDH>  \n" + "    <XFYHZH>中国农业银行股份有限公</XFYHZH>  \n"
            + "    <GFSH>91341881052913872E</GFSH>  \n" + "    <GFMC>宁国双赢再生资源有限公司</GFMC>  \n"
            + "    <GFDZDH>宁国市汪溪街道滨江大道11号 0563-4022134</GFDZDH>  \n"
            + "    <GFYHZH>中国工商银行宁国市支行 1317090009200378867</GFYHZH>  \n" + "    <KPR>晏婵</KPR>  \n"
            + "    <SKR></SKR>  \n" + "    <FHR>孙冯莹</FHR>  \n" + "    <YFPDM></YFPDM>  \n" + "    <YFPHM></YFPHM>  \n"
            + "    <HPTZDBH></HPTZDBH>  \n" + "    <JSHJ>-100998.99</JSHJ>  \n" + "    <HJJE>-99999.00</HJJE>  \n"
            + "    <HJSE>-999.99</HJSE>  \n" + "    <BZ></BZ>  \n" + "    <COMMON_NODES size=\"3\">\n"
            + "      <COMMON_NODE> \n" + "        <NAME>SJ</NAME>  \n" + "        <VALUE></VALUE> \n"
            + "      </COMMON_NODE>  \n" + "      <COMMON_NODE> \n" + "        <NAME>EMAIL</NAME>  \n"
            + "        <VALUE>73@qq.com</VALUE> \n" + "      </COMMON_NODE>  \n" + "      <COMMON_NODE> \n"
            + "        <NAME></NAME>  \n" + "        <VALUE></VALUE> \n" + "      </COMMON_NODE> \n"
            + "    </COMMON_NODES>  \n" + "    <FPXMXX COUNT=\"1\"> \n" + "      <FPXM> \n"
            + "        <FPHXZ>0</FPHXZ>  \n" + "        <XMMC>*黑色金属冶炼压延品*废钢</XMMC>  \n" + "        <GGXH>废生铁</GGXH>  \n"
            + "        <JLDW>吨</JLDW>  \n" + "        <XMSL>-25.5048727698</XMSL>  \n"
            + "        <XMDJ>3920.78019375</XMDJ>  \n" + "        <XMJE>-99999.00</XMJE>  \n"
            + "        <SL>0.01</SL>  \n" + "        <SE>-999.99</SE>  \n" + "        <HSDJ>3959.9879957</HSDJ>  \n"
            + "        <HSJE>-100998.99</HSJE>  \n" + "        <SPBM>1080207990000000000</SPBM>  \n"
            + "        <SFYHZC>0</SFYHZC>  \n" + "        <YHZCNR></YHZCNR>  \n" + "        <LSLBS></LSLBS> \n"
            + "      </FPXM>  \n" + "    </FPXMXX> \n" + "  </INPUT> \n" + "</FPKJINPUT>";
        String pwd = "MEGKDFEEMAGRWWLMFKFDDDEL";
        String sh = "91370211MA3RWWLM2K";
        try {
            // System.out.println("输出*****" + xml);
            // byte[] decodeContent = xml.getBytes("GBK");
            // byte[] data = TripleDESUtil.encryptMode(pwd, decodeContent);
            // byte[] jm = TripleDESUtil.encode(data);
            //
            // byte[] shh = TripleDESUtil.encode(TripleDESUtil.encryptMode(pwd, sh.getBytes("GBK")));
            //
            // System.out.println("税号：" + new String(shh));
            // System.out.println("加密前：" + new String(decodeContent));
            // System.out.println("base64加密前：" + new String(data));
            // System.out.println("base64加密后：" + new String(jm));

            // byte[] decodeContent1 = xml.getBytes("GBK");
            // byte[] jm1 = TripleDESUtil.encode(decodeContent1);
            // System.out.println("base64加密后：" + new String(jm1));

            String a = new String(TripleDESUtil.encryptMode(pwd, sh.getBytes("GBK")));
            System.out.println("3des加密：" + a);
            String b = new String(TripleDESUtil.encode(sh.getBytes("GBK")));
            System.out.println("base64加密：" + b);

            byte[] shh = TripleDESUtil.encode(TripleDESUtil.encryptMode(pwd, sh.getBytes("GBK")));
            String c = new String(shh, "GBK");
            System.out.println("加密后" + c);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
